package com.rzx;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import com.google.common.hash.HashCode;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

/**
 * 
 * @author penn
 * @date May 14, 2020 7:15:51 PM
 */
public class IdAuthReuqest {

	private String clientId;
	private String clientSecret;
	private String userId;

	public IdAuthReuqest(String clientId, String clientSecret, String userId) {
		this.clientId = clientId;
		this.clientSecret = clientSecret;
		this.userId = userId;

	}

	private static final int TIMEOUT = 10000;

	private static final String GETTOKEN_URL = "http://authapi.topfreeweb.net/idauth-server/idauth/token/getToken"; // 获取token接口
	private static final String LIVENESS_URL = "http://authapi.topfreeweb.net/idauth-server/idauth/auth/liveness/slient"; // 活体认证接口
	private static final String THREEELEMENTS = "http://authapi.topfreeweb.net/idauth-server/idauth/auth/3e"; // 三要素认证接口

	/**
	 * 实名认证获取TOKEN调用DEMO
	 * 
	 * @return TOKEN
	 * @throws Exception
	 */
	public String getToken() throws Exception {

		if (StringUtils.isEmpty(clientId) || StringUtils.isEmpty(clientSecret) || StringUtils.isAllBlank(userId)) {
			System.out.println("请先配置CLIENT_ID，CLIENT_SECRET，USER_ID ");
			return null;
		}

		System.out.println("正在获取Token，请稍后......");
		// 初始化Client
		CloseableHttpClient httpClient = HttpClients.createDefault();
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(TIMEOUT)
				.setConnectionRequestTimeout(TIMEOUT).setSocketTimeout(TIMEOUT).setRedirectsEnabled(true).build();

		// 设置参数
		List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
		list.add(new BasicNameValuePair("clientId", clientId)); // 请求参数
		list.add(new BasicNameValuePair("clientSecret", clientSecret)); // 请求参数

		// 设置entity
		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");

		// 接口地址和请求设置
		HttpPost httpPost = new HttpPost(GETTOKEN_URL);
		httpPost.setConfig(requestConfig);
		httpPost.setEntity(entity);

		// 发送请求并接受结果
		HttpResponse httpResponse = httpClient.execute(httpPost);

		// 对结果的处理
		if (httpResponse != null) {
			System.out.println("请求响应代码:::" + httpResponse.getStatusLine().getStatusCode());
			if (httpResponse.getStatusLine().getStatusCode() == 200) {
				String result = EntityUtils.toString(httpResponse.getEntity());
				System.out.println("获取Token请求的结果:::" + result);
				JsonObject jsonObject = new JsonParser().parse(result).getAsJsonObject();
				return jsonObject.get("data").getAsJsonObject().get("obj").getAsJsonObject().get("token").toString()
						.replaceAll("\"", "");
			}
		}

		System.out.println("获取Token失败，请检查密钥信息！！！");
		return null;
	}

	/**
	 * 实名认证活体验证接口调用DEMO
	 * 
	 * @param path     文件
	 * @param idNumber 身份证号号码
	 * @param name     姓名
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("deprecation")
	public String livenessRequest(Path path, String token, String idNumber, String name) throws Exception {

		if (path == null || StringUtils.isEmpty(token) || StringUtils.isEmpty(idNumber) || StringUtils.isEmpty(name)) {
			System.out.println("请先设置请求参数！！！");
			return null;
		}

		System.out.println("正在进行活体验证，请稍后......");

		// Client初始化
		CloseableHttpClient httpClient = HttpClients.createDefault();
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(TIMEOUT)
				.setConnectionRequestTimeout(TIMEOUT).setSocketTimeout(TIMEOUT).setRedirectsEnabled(true).build();

		// 设置签名
		StringBuffer toSign = new StringBuffer();
		toSign.append("idNumber=").append(idNumber).append("&");
		toSign.append("name=").append(name).append("&");
		toSign.append("video=").append(path.getFileName()).append("&");
		toSign.append(userId);
		HashFunction hashFunction = Hashing.md5();
		HashCode signHash = hashFunction.hashString(toSign.toString(), StandardCharsets.UTF_8);

		// 创建请求表单
		MultipartEntityBuilder builder = MultipartEntityBuilder.create();
		builder.setCharset(Charset.forName(HTTP.UTF_8));
		builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

		// 请求参数中文乱码的处理
		ContentType contentType = ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8);
		StringBody nameBody = new StringBody(name, contentType);
		builder.addPart("name", nameBody); // 姓名
		builder.addTextBody("idNumber", idNumber); // 身份证号码
		builder.addBinaryBody("video", path.toFile()); // 视频文件
		builder.addTextBody("sign", signHash.toString()); // 签名

		// 配置接口地址和请求设置
		HttpPost httpPost = new HttpPost(LIVENESS_URL);
		httpPost.setConfig(requestConfig);

		// 设置Token
		httpPost.setHeader("Authorization", "Bearer " + token);

		// 填充表单
		httpPost.setEntity(builder.build());

		// 发送请求并接受结果
		HttpResponse httpResponse = httpClient.execute(httpPost);

		// 对结果的处理
		String strResult = "";
		if (httpResponse != null) {
			System.out.println("请求响应代码:::" + httpResponse.getStatusLine().getStatusCode());
			if (httpResponse.getStatusLine().getStatusCode() == 200) {
				strResult = EntityUtils.toString(httpResponse.getEntity());
			}
		}
		return strResult;
	}

	/**
	 * 实名认证3要素接口调用DEMO
	 * 
	 * @param path     文件
	 * @param idNumber 身份证号号码
	 * @param name     姓名
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("deprecation")
	public String threeElementsRequest(String facePhotoBase64, String token, String idNumber, String name)
			throws Exception {

		if (StringUtils.isEmpty(facePhotoBase64) || StringUtils.isEmpty(token) || StringUtils.isEmpty(idNumber)
				|| StringUtils.isEmpty(name)) {
			System.out.println("请先设置请求参数！！！");
			return null;
		}

		System.out.println("正在进行3要素验证，请稍后......");

		// Client初始化
		CloseableHttpClient httpClient = HttpClients.createDefault();
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(TIMEOUT)
				.setConnectionRequestTimeout(TIMEOUT).setSocketTimeout(TIMEOUT).setRedirectsEnabled(true).build();

		// 设置签名
		StringBuffer toSign = new StringBuffer();
		toSign.append("facePhotoBase64=").append(facePhotoBase64).append("&");
		toSign.append("idNumber=").append(idNumber).append("&");
		toSign.append("name=").append(name).append("&");
		toSign.append(userId);
		HashFunction hashFunction = Hashing.md5();
		HashCode signHash = hashFunction.hashString(toSign.toString(), StandardCharsets.UTF_8);

		// 创建请求表单
		MultipartEntityBuilder builder = MultipartEntityBuilder.create();
		builder.setCharset(Charset.forName(HTTP.UTF_8));
		builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

		// 请求参数中文乱码的处理
		ContentType contentType = ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8);
		StringBody nameBody = new StringBody(name, contentType);
		builder.addPart("name", nameBody); // 姓名
		builder.addTextBody("idNumber", idNumber); // 身份证号码
		builder.addTextBody("facePhotoBase64", facePhotoBase64); // 图片Base64
		builder.addTextBody("sign", signHash.toString()); // 签名

		// 配置接口地址和请求设置
		HttpPost httpPost = new HttpPost(THREEELEMENTS);
		httpPost.setConfig(requestConfig);

		// 设置Token
		httpPost.setHeader("Authorization", "Bearer " + token);

		// 填充表单
		httpPost.setEntity(builder.build());

		// 发送请求并接受结果
		HttpResponse httpResponse = httpClient.execute(httpPost);

		// 对结果的处理
		String strResult = "";
		if (httpResponse != null) {
			System.out.println("请求响应代码:::" + httpResponse.getStatusLine().getStatusCode());
			if (httpResponse.getStatusLine().getStatusCode() == 200) {
				strResult = EntityUtils.toString(httpResponse.getEntity());
			}
		}
		return strResult;
	}

}
